package com.google.bitcoin.store;


import com.google.bitcoin.core.Address;
import com.google.bitcoin.core.Wallet;
import com.google.bitcoin.core.WalletPony;
import com.google.bitcoin.core.NetworkParameters;
import com.google.protobuf.ByteString;

import org.bitcoinj.wallet.Protos;

import java.io.ByteArrayOutputStream;
import java.io.ByteArrayInputStream;
import java.io.ObjectOutputStream;
import java.io.ObjectInputStream;
import java.io.IOException;

import java.util.Collection;
import java.util.LinkedList;

public class WalletPonySerializer extends WalletExtensionSerializer
{
    public Wallet newWallet(NetworkParameters params)
    {
        return new WalletPony(params);
    }

    public void readExtension(Wallet w, Protos.Extension extProto) 
    {
        try
        {
            if (extProto.getId().equals("WalletRnd.change_addresses"))
            {
                WalletPony wallet = (WalletPony)w;
                try
                {
                    ObjectInputStream ois =
                        new ObjectInputStream(
                        new ByteArrayInputStream(
                        extProto.getData().toByteArray() ));

                    Collection<Address> lst = (Collection<Address>) ois.readObject();

                    wallet.setChangeAddresses(lst);
                }
                catch(ClassNotFoundException e)
                {
                    throw new IOException(e);
                }

            }
            else if (extProto.getId().equals("WalletRnd.proscribed_addresses"))
            {
                WalletPony wallet = (WalletPony)w;
                try
                {
                    ObjectInputStream ois =
                        new ObjectInputStream(
                        new ByteArrayInputStream(
                        extProto.getData().toByteArray() ));

                    Collection<Address> lst = (Collection<Address>) ois.readObject();

                    wallet.setProscribedFromAddresses(lst);
                }
                catch(ClassNotFoundException e)
                {
                    throw new IOException(e);
                }


            }
            else
            {
                super.readExtension(w, extProto);
            }
        }
        catch(IOException e)
        {
            throw new IllegalArgumentException(e);
        }
    }

    /**
     * Get collection of extensions to add, should be overridden by any class
     * adding wallet extensions
     *
     */
    public Collection<Protos.Extension> getExtensionsToWrite(Wallet wallet) 
    {
        try
        {
            LinkedList<Protos.Extension> lst = new LinkedList<Protos.Extension>();
            if (wallet instanceof WalletPony)
            {
                WalletPony r = (WalletPony) wallet;
                if (r.getChangeAddresses() != null)
                {

                    Protos.Extension.Builder e = Protos.Extension.newBuilder();
                    e.setId("WalletRnd.change_addresses");
                    e.setMandatory(true);
                    ByteArrayOutputStream b_out = new ByteArrayOutputStream();
                    ObjectOutputStream oos = new ObjectOutputStream(b_out);

                    oos.writeObject(r.getChangeAddresses());
                    oos.flush();
                    e.setData(ByteString.copyFrom(b_out.toByteArray()));

                    lst.add(e.build());

                }
                if (r.getProscribedFromAddresses() != null)
                {
                    Protos.Extension.Builder e = Protos.Extension.newBuilder();
                    e.setId("WalletRnd.proscribed_addresses");
                    e.setMandatory(true);
                    ByteArrayOutputStream b_out = new ByteArrayOutputStream();
                    ObjectOutputStream oos = new ObjectOutputStream(b_out);

                    oos.writeObject(r.getProscribedFromAddresses());
                    oos.flush();
                    e.setData(ByteString.copyFrom(b_out.toByteArray()));

                    lst.add(e.build());

                }


            }


            lst.addAll(super.getExtensionsToWrite(wallet));
            return lst;
        }
        catch(IOException e)
        {
            throw new IllegalArgumentException(e);
        }
    }

 

}
